package znet

import (
	"context"
	"fmt"
	"io"
	"net"

	"zinx-my/ziface"
)

type Connection struct {
	Conn      *net.TCPConn
	ConnID    uint32
	isClosed  bool
	handleAPI ziface.HandleFunc

	ExitChan chan bool
	ctx      context.Context
}

func NewConnection(conn *net.TCPConn, connID uint32, handler ziface.HandleFunc) *Connection {
	return &Connection{
		Conn:      conn,
		ConnID:    connID,
		isClosed:  false,
		handleAPI: handler,
		ExitChan:  make(chan bool, 1),
		ctx:       context.Background(), // 自己发挥的
	}
}

func (c *Connection) Context() context.Context {
	return c.ctx
}

func (c *Connection) StartReader() {
	fmt.Println("StartReader() goroutine is running...")
	defer fmt.Println("ConnID:", c.ConnID, "StartReader is exit, remote addr is", c.Conn.RemoteAddr().String())
	defer c.Stop()

	for {
		buf := make([]byte, 512)
		cnt, err := c.Conn.Read(buf)
		if err != nil {
			fmt.Println("read conn buf error:", err)
			if err == io.EOF {
				break
			}
			continue
		}

		// TODO: 误写两遍，结果回显时，双倍了，但个别时候正常
		//       可能是粘包问题，因为 TCP 是一个面向流的协议，没有明确的消息边界。
		//       多数时两遍当成了一遍读，少数读取时只接收到了一条，且读取时是间隔1s的，所以就被舍弃了？
		// if _, err := c.Conn.Write(buf[:cnt]); err != nil {
		// 	fmt.Println("write back buf error:", err)
		// }

		if err := c.handleAPI(c.Conn, buf, cnt); err != nil {
			fmt.Println("ConnID", c.ConnID, "handle is error", err)
			continue
		}
	}
}

func (c *Connection) Start() {
	fmt.Println("Conn Start()... ConnID:", c.ConnID)

	// if c.isClosed == false {
	// 	return
	// }
	// c.isClosed = false

	go c.StartReader()
}

func (c *Connection) Stop() {
	fmt.Println("Conn Stop()... ConnID:", c.ConnID)

	if c.isClosed {
		return
	}

	c.isClosed = true
	c.Conn.Close()
	close(c.ExitChan)
}

func (c *Connection) GetTCPConnection() *net.TCPConn {
	return c.Conn
}

func (c *Connection) GetConnID() uint32 {
	return c.ConnID
}
